快要結束了,今天要繼續寫 admin_bp
。今天的內容會用到 JS,但我不會多加解釋。
我們直接把 admin_dashboard_posts_backend
和 admin_dashboard_comments_backend
一起看,,因為他們真的很接近,一樣從資料庫開始。
def delete_post_admin(post_id):
post = Posts.query.filter_by(id=post_id).first()
comments = Comments.query.filter_by(post_id=post_id).all()
db.session.delete(post)
for comment in comments:
db.session.delete(comment)
db.session.commit()
def delete_comment_admin(comment_id):
comment = Comments.query.filter_by(id=comment_id).first()
db.session.delete(comment)
db.session.commit()
雖然兩個都是刪除,但刪除貼文比較麻煩一點,因為留言是附在貼文下面的,所以要連著留言一起刪掉才行。
在進入 HTML 之前,我們要先看看 JS。
admin.js
function del_post(post_id) {
$.ajax({
url: "/admin_dashboard_posts_backend",
type: "delete",
data: JSON.stringify({ "post_id": post_id }),
dataType: "json",
})
.always(function (r) {
if (r.status == 200) {
alert("OK.", "success");
}
else {
alert("Error.", "alert");
}
})
}
function del_comment(comment_id) {
$.ajax({
url: "/admin_dashboard_comments_backend",
type: "delete",
data: JSON.stringify({ "comment_id": comment_id }),
dataType: "json",
})
.always(function (r) {
if (r.status == 200) {
alert("OK.", "success");
}
else {
alert("Error.", "alert");
}
})
}
這裡我們使用了 jquery 來做 ajax,在使用者按下刪除按鈕之後就送出 request 讓後端刪除。
接下來是 HTML,基本上就是昨天寫好的檔案,只是要稍微加一些東西。
admin_dashboard_comments.html
{% block extra_import %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="/static/admin.js"></script>
{% endblock %}
<button onclick="del_comment({{ comment['id'] }});">Delete</button>
admin_dashboard_posts.html
{% block extra_import %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="/static/admin.js"></script>
{% endblock %}
<button onclick="del_post({{ post['id'] }});">Delete</button>
我們多引入了剛剛寫的 admin.js
以及 jquery 的 JS 檔案。接著我們調整了一下刪除的按鈕,把他多加了一個 onclick
來執行剛剛寫的 JS。
最後要看到路徑的部分,兩個非常接近。
@admin_bp.route("/admin_dashboard_posts_backend", methods=["DELETE"])
def admin_dashboard_posts_backend():
data = request.get_json(force=True)
post_id = data["post_id"]
try:
delete_post_admin(post_id)
return "OK"
except:
abort(400)
@admin_bp.route("/admin_dashboard_comments_backend", methods=["DELETE"])
def admin_dashboard_comments_backend():
data = request.get_json(force=True)
comment_id = data["comment_id"]
try:
delete_comment_admin(comment_id)
return "OK"
except:
abort(400)
在這邊我們又看到 request
並用了他的 get_json
函式。這邊加了一個 force=True
,是因為 flask 會偵測 request
的 MIME type,如果不是 JSON 他就會不讓你 parse,加了這個參數之後他不管如何就是會 parse,但如果內容不是 JSON 的話他還是會噴錯誤。接下來就是嘗試刪除,不成功的話就 abort
。
最後要做的部分是管理使用者頁面的更新和刪除按鈕。一樣先從資料庫看起。
def delete_user(user_id):
user = Users.query.filter_by(id=user_id).first()
posts = Posts.query.filter_by(author_id=user_id).all()
for post in posts:
delete_post_admin(post)
comments = Comments.query.filter_by(author_id=user_id).all()
for comment in comments:
db.session.delete(comment)
db.session.delete(user)
db.session.commit()
這邊只有刪除的,因為更新的函式在之前寫過了。跟剛剛刪除貼文類似,我們也需要把使用者的貼文和留言一起刪掉。
再來一樣先看看 JS,更新的部分跟剛剛稍微有些不同。
admin.js
function del_user(user_id) {
$.ajax({
url: "/manage_user_backend",
type: "delete",
data: JSON.stringify({ "user_id": user_id }),
dataType: "json",
})
.always(function (r) {
if (r.status == 200) {
alert("OK.", "success");
}
else {
alert("Error.", "alert");
}
})
}
function update_user(element) {
var parent = element.parentElement;
var user_id = parent.children[0].innerText;
var email = parent.children[2].value;
var is_admin = parent.children[3].checked;
var data = { "user_id": user_id, "username": username, "email": email, "is_admin": is_admin }
$.ajax({
url: "/manage_user_backend",
type: "patch",
data: JSON.stringify(data),
dataType: "json",
})
.always(function (r) {
if (r.status == 200) {
alert("OK.", "success");
}
else {
alert("Error.", "alert");
}
})
}
光看這樣子應該無法理解 update_user
的 element
在幹嘛,所以我們直接看看 HTML,JS 的引入就不重複打了。
manage_user.html
<span>{{ user['id'] }}</span>
<span>{{ user['username'] }}</span>
<input type="email" value="{{ user['email'] }}">
<input type="checkbox" {% if user['is_admin'] %} checked {% endif %}>
<input type="text" value="{{ user['introduction'] }}">
<span>{{ user['register_time'] }}</span>
<button onclick="del_user({{ user['id'] }});">Delete</button>
<button onclick="update_user(this);">Update</button>
我們修改了底下的兩個按鈕,更新的按鈕直接把自己這個 element
傳入 JS,所以剛剛看到的 element
就是這個按鈕。然後在 update_user
裡面就去把每個欄位的值抓出來,丟給後端 python 處理。
最後來看到路徑。
@admin_bp.route("/manage_user_backend", methods=["PATCH", "DELETE"])
def manage_user_backend():
if request.method == "PATCH":
data = request.get_json(force=True)
if (
update_user_data(
data["user_id"], email=data["email"], is_admin=data["is_admin"]
)
== True
):
return "OK"
else:
abort(400)
if request.method == "DELETE":
data = request.get_json(force=True)
user_id = data["user_id"]
try:
delete_user(user_id)
return "OK"
except:
abort(400)
因為有更新和刪除兩個功能,所以要先判斷 request.method
,然後再分別去更新,有問題的話就 abort(400)
。